package com.nian.hbase.base.aop;

import com.nian.hbase.base.model.HBaseRowModel;
import com.nian.hbase.base.model.HBaseTableModel;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author zhangmj
 * @date 2020/4/23 17:21
 */
public class ParsingAnnotation {

    public static<T> HBaseTableModel readModel(T model) {
        try{
            if(model != null){
                List<HBaseRowModel> list = new LinkedList<>();
                String rowNum = UUID.randomUUID().toString();
                Class clazz = model.getClass();
                HbaseTable hbaseTable = (HbaseTable) clazz.getAnnotation(HbaseTable.class);
                String tableName = hbaseTable.tableName();
                Field[] fields = clazz.getDeclaredFields();
                Set<String> familyList = new LinkedHashSet<>();
                for (int i = 0; i < fields.length; i++) {
                    Field field = fields[i];
                    if(field.isAnnotationPresent(HbaseColumn.class)){
                        field.setAccessible(true);
                        Object value = field.get(model);
                        String v = value != null?value.toString():null;
                        HbaseColumn hbaseColumn = field.getAnnotation(HbaseColumn.class);
                        HBaseRowModel rowModel = new HBaseRowModel(tableName, rowNum, hbaseColumn.family(), hbaseColumn.qualifier(), v);
                        list.add(rowModel);
                        familyList.add(hbaseColumn.family());
                    }
                }
                return new HBaseTableModel(tableName, list,familyList.toArray(new String[familyList.size()]));
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static<T> HBaseTableModel readModel(Class clazz) {
        try{
            if(clazz != null){
                List<HBaseRowModel> list = new LinkedList<>();
                String rowNum = UUID.randomUUID().toString();
                HbaseTable hbaseTable = (HbaseTable) clazz.getAnnotation(HbaseTable.class);
                String tableName = hbaseTable.tableName();
                Field[] fields = clazz.getDeclaredFields();
                Set<String> familyList = new LinkedHashSet<>();
                for (int i = 0; i < fields.length; i++) {
                    Field field = fields[i];
                    if(field.isAnnotationPresent(HbaseColumn.class)){
                        field.setAccessible(true);
                        HbaseColumn hbaseColumn = field.getAnnotation(HbaseColumn.class);
                        HBaseRowModel rowModel = new HBaseRowModel(tableName, rowNum, hbaseColumn.family(), hbaseColumn.qualifier());
                        list.add(rowModel);
                        familyList.add(hbaseColumn.family());
                    }
                }
                return new HBaseTableModel(tableName, list,familyList.toArray(new String[familyList.size()]));
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }


    public static<T> T initModel(Class<T> clazz, List<HBaseRowModel> list) {
        try{
            if(clazz != null && CollectionUtils.isNotEmpty(list)){
                T newClazz = clazz.newInstance();
                Field[] fields = clazz.getDeclaredFields();
                for (HBaseRowModel model:list) {
                    boolean flag = true;
                    for (Field field:fields) {
                        if(field.isAnnotationPresent(HbaseId.class)){
                            field.setAccessible(true);
                            field.set(newClazz, model.getRowName());
                        } else if(flag && field.isAnnotationPresent(HbaseColumn.class)){
                            field.setAccessible(true);
                            HbaseColumn hbaseColumn = field.getAnnotation(HbaseColumn.class);
                            if(hbaseColumn != null && StringUtils.equals(hbaseColumn.family(), model.getFamily()) && StringUtils.equals(hbaseColumn.qualifier(), model.getQualifier())){
                                field.set(newClazz, model.getValue());
                                flag = false;
                            }
                        }
                    }
                }
                return newClazz;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
